<template>
  <div class="app-container">
    <el-card>
      <div v-if="showSearch" slot="header" class="clearfix">
        <!--头部工具过滤-->
        <el-input
          v-model="listQuery.title"
          size="mini"
          maxlength="255"
          clearable
          style="width: 200px;margin-right: 5px;"
          placeholder="请输入菜单名称"
        />
        <el-button type="success" size="mini" icon="el-icon-search" @click="handleFilter">搜索</el-button>
        <el-button type="warning" size="mini" icon="el-icon-refresh-left" @click="resetForm">重置</el-button>
      </div>
      <div class="opts">
        <!--左侧-->
        <el-button type="primary" icon="el-icon-plus" size="mini" @click="handleCreate">添加</el-button>
        <el-button
          type="success"
          :disabled="hasEdiObj"
          icon="el-icon-edit"
          size="mini"
          @click="handleUpdate(selectionChange[0])"
        >修改
        </el-button>
        <el-button type="danger" :disabled="hasDelObj" icon="el-icon-delete" size="mini" @click="handleDelete">删除
        </el-button>
        <!--右侧-->
        <right-toolbar :show-search.sync="showSearch" :columns="columnNames" :table-ref="tableRef" @queryTable="resetForm" />
      </div>
      <!--表格数据-->
      <el-table
        ref="table"
        v-loading="loading"
        :data="tableData"
        :expand-row-keys="tableData.map(m => m.id)"
        style="width: 100%;"
        row-key="id"
        size="mini"
        element-loading-text="正在努力加载中..."
        :tree-props="{children: 'children', hasChildren: 'hasChildren'}"
        border
        fit
        @selection-change="handleSelectionChange"
      >
        <el-table-column type="selection" width="55" />
        <el-table-column v-if="columns[0].visible" show-overflow-tooltip prop="title" width="200px" label="菜单标题">
          <template slot-scope="scope">
            <svg-icon
              v-if="scope.row.icon"
              style="width: 20px;height: 20px;margin-right: 10px;"
              :icon-class="scope.row.icon"
              class-name="disabled"
            />
            {{ scope.row.title }}
          </template>
        </el-table-column>
        <el-table-column v-if="columns[1].visible" align="center" prop="type" width="100px" label="菜单类型">
          <template slot-scope="scope">
            <el-tag v-if="scope.row.type === 0">
              目录
            </el-tag>
            <el-tag v-if="scope.row.type === 1" type="success">
              菜单
            </el-tag>
            <el-tag v-if="scope.row.type === 2" type="warning">
              按钮
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column v-if="columns[2].visible" show-overflow-tooltip prop="component" label="组件路径" />
        <el-table-column v-if="columns[3].visible" show-overflow-tooltip prop="permission" width="200px" label="权限标识" />
        <el-table-column v-if="columns[4].visible" prop="cache" width="70px" label="缓存">
          <template slot-scope="scope">
            <el-switch
              v-if="scope.row.type===1"
              v-model="scope.row.cache"
              @change="updateCache({id: scope.row.id,cache: scope.row.cache},scope.row)"
            />
          </template>
        </el-table-column>
        <el-table-column v-if="columns[5].visible" prop="frame" width="70px" label="外链">
          <template slot-scope="scope">
            <el-switch
              v-if="scope.row.type!==2"
              v-model="scope.row.frame"
              @change="updateFrame({id: scope.row.id,frame: scope.row.frame},scope.row)"
            />
          </template>
        </el-table-column>
        <el-table-column v-if="columns[6].visible" prop="hidden" width="70px" label="隐藏">
          <template slot-scope="scope">
            <el-switch
              v-if="scope.row.type!==2"
              v-model="scope.row.hidden"
              @change="updateHidden({id: scope.row.id,hidden: scope.row.hidden},scope.row)"
            />
          </template>
        </el-table-column>
        <el-table-column v-if="columns[7].visible" prop="sort" width="80px" label="排序" />
        <!--        <el-table-column v-if="columns[8].visible" prop="createdBy" width="85px" label="创建人">
          <template scope="scope">
            {{ scope.row.createdUser?scope.row.createdUser.name:'' }}
          </template>
        </el-table-column>-->
        <el-table-column v-if="columns[9].visible" prop="createTime" width="160px" label="创建时间" />
        <el-table-column align="center" width="170px" label="操作">
          <template slot-scope="scope">
            <el-popconfirm title="您确定要删除吗？" style="margin-right: 5px" @confirm="deleteByIds([scope.row.id])">
              <el-button slot="reference" type="danger" icon="el-icon-delete" size="mini" />
            </el-popconfirm>
            <el-button type="primary" icon="el-icon-edit" size="mini" @click="handleUpdate(scope.row)" />
            <el-button
              type="primary"
              :disabled="scope.row.type===2"
              icon="el-icon-plus"
              size="mini"
              @click="handleSubCreate(scope.row)"
            />
          </template>
        </el-table-column>
      </el-table>
    </el-card>

    <!--对话框-->
    <el-dialog :title="title" :visible.sync="dialogVisible" width="40%" @open="openDialog">
      <el-row :gutter="15">
        <el-form ref="formData" :model="formData" :rules="rules" size="mini" label-width="100px">
          <el-col :span="24">
            <el-form-item label="菜单类型" prop="type">
              <el-radio-group v-model="formData.type">
                <el-radio-button label="0">目录</el-radio-button>
                <el-radio-button label="1">菜单</el-radio-button>
                <el-radio-button label="2">权限按钮</el-radio-button>
              </el-radio-group>
            </el-form-item>
          </el-col>
          <el-col :span="24">
            <el-form-item v-if="formData.type.toString()==='2'" label="按钮名称" prop="title">
              <el-input
                v-model="formData.title"
                placeholder="请输入按钮名称"
                maxlength="255"
                show-word-limit
                clearable
                :style="{width: '100%'}"
              />
            </el-form-item>
          </el-col>
          <el-col :span="24">
            <el-form-item v-if="formData.type.toString()!=='2'" label="菜单标题" prop="title">
              <el-input
                v-model="formData.title"
                placeholder="请输入菜单标题"
                maxlength="255"
                show-word-limit
                clearable
                :style="{width: '100%'}"
              />
            </el-form-item>
          </el-col>
          <el-col :span="24">
            <el-form-item v-show="formData.type.toString()==='1'" label="组件名称" prop="pid">
              <el-input
                v-model="formData.name"
                placeholder="请输入组件名称"
                maxlength="255"
                show-word-limit
                clearable
                :style="{width: '100%'}"
              />
            </el-form-item>
          </el-col>
          <el-col :span="24">
            <el-form-item v-show="formData.type.toString()==='1'" label="组件路径" prop="pid">
              <el-input
                v-model="formData.component"
                placeholder="请输入组件路径"
                maxlength="255"
                show-word-limit
                clearable
                :style="{width: '100%'}"
              />
            </el-form-item>
          </el-col>
          <el-col :span="24">
            <el-form-item v-if="formData.type.toString()!=='2'" label="路由地址" prop="path">
              <el-input
                v-model="formData.path"
                placeholder="请输入路由地址"
                maxlength="255"
                show-word-limit
                clearable
                :style="{width: '100%'}"
              />
            </el-form-item>
          </el-col>
          <el-col :span="24">
            <el-form-item v-show="formData.type.toString()!=='0'" label="权限标识" prop="permission">
              <el-input
                v-model="formData.permission"
                placeholder="请输入权限标识"
                maxlength="255"
                show-word-limit
                clearable
                :style="{width: '100%'}"
              />
            </el-form-item>
          </el-col>
          <el-col :span="24">
            <el-form-item v-show="formData.type.toString()!=='2'" label="菜单图标" prop="icon">
              <el-popover placement="bottom-start" width="500" trigger="click" @show="$refs['iconSelect'].reset()">
                <IconSelect ref="iconSelect" @selected="selected" />
                <el-input slot="reference" v-model="formData.icon" placeholder="点击选择图标" readonly>
                  <svg-icon
                    v-if="formData.icon"
                    slot="prefix"
                    :icon-class="formData.icon"
                    class="el-input__icon"
                    style="height: 32px;width: 16px;"
                  />
                  <i v-else slot="prefix" class="el-icon-search el-input__icon" />
                </el-input>
              </el-popover>
            </el-form-item>
          </el-col>
          <el-col :span="24">
            <el-form-item label="排序" prop="sort">
              <el-input-number
                v-model="formData.sort"
                placeholder="排序"
                :min="0"
                :max="9999"
                :step="1"
                :style="{width: '100%'}"
                controls-position="right"
              />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item v-show="formData.type.toString()!=='2'" label="外链菜单" prop="frame">
              <el-radio-group v-model="formData.frame" size="mini">
                <el-radio-button :label="true">是</el-radio-button>
                <el-radio-button :label="false">否</el-radio-button>
              </el-radio-group>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item v-show="formData.type.toString()!=='2'" label="菜单可见" prop="hidden">
              <el-radio-group v-model="formData.hidden" size="mini">
                <el-radio-button :label="false">是</el-radio-button>
                <el-radio-button :label="true">否</el-radio-button>
              </el-radio-group>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item v-show="formData.type.toString()==='1'" label="缓存菜单" prop="cache">
              <el-radio-group v-model="formData.cache" size="mini">
                <el-radio-button :label="true">是</el-radio-button>
                <el-radio-button :label="false">否</el-radio-button>
              </el-radio-group>
            </el-form-item>
          </el-col>
          <el-col :span="24">
            <el-form-item label="上级目录" prop="pid">
              <treeselect
                v-model="formData.pid"
                :append-to-body="true"
                z-index="9999"
                search-nested
                :show-count="true"
                :options="menus"
                :normalizer="normalizer"
                placeholder="选择上级类目"
                no-children-text="当前菜单下无子菜单"
                no-results-text="查无此菜单"
              >
                <label
                  slot="option-label"
                  slot-scope="{ node, shouldShowCount, count, labelClassName, countClassName }"
                  :class="labelClassName"
                >
                  <svg-icon
                    v-if="node.raw.icon"
                    style="width: 15px;height: 15px;margin-right: 10px;"
                    :icon-class="node.raw.icon"
                    class-name="disabled"
                  />
                  <span v-if="node.raw.type===0" style="color: #08adee">目录</span>
                  <span v-if="node.raw.type===1" style="color: #08ea2d">菜单</span>
                  <span v-if="node.raw.type===2" style="color: #f1e60c">按钮</span>
                  {{ node.label }}
                  <span v-if="shouldShowCount" :class="countClassName">({{ count }})</span>
                </label>
              </treeselect>
            </el-form-item>
          </el-col>
        </el-form>
      </el-row>
      <div slot="footer" class="dialog-footer">
        <el-button size="mini" @click="dialogVisible = false">
          取消
        </el-button>
        <el-button type="primary" size="mini" @click="title==='添加'?create():updateById()">
          提交
        </el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import RightToolbar from '@/components/RightToolbar'
import { create, deleteByIds, findAll, findByPid, updateById, tree } from '@/api/menu'
import IconSelect from '@/components/IconSelect'
import Treeselect from '@riophae/vue-treeselect'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
import { Notification } from 'element-ui'

export default {
  name: 'Index',
  components: { IconSelect, Treeselect, RightToolbar },
  data() {
    return {
      columnNames: [],
      showSearch: true,
      tableColumns: [],
      allColumnsSelected: true,
      allColumnsSelectedIndeterminate: false,
      columns: [
        { key: 0, label: `菜单标题`, visible: true },
        { key: 1, label: `菜单类型`, visible: true },
        { key: 2, label: `组件路径`, visible: true },
        { key: 3, label: `权限标识`, visible: true },
        { key: 4, label: `缓存`, visible: true },
        { key: 5, label: `外链`, visible: true },
        { key: 6, label: `隐藏`, visible: true },
        { key: 7, label: `排序`, visible: true },
        { key: 8, label: `创建人`, visible: true },
        { key: 9, label: `创建时间`, visible: true }
      ],
      tableRef: null,
      normalizer(node) {
        return {
          id: node.id,
          label: node.name,
          icon: node.icon,
          type: node.type,
          children: node.children
        }
      },
      screenHeight: `${document.documentElement.clientHeight}` - 330,
      selectionChange: null,
      loading: true,
      tableData: [],
      menus: [{ id: 0, name: '顶层菜单', icon: '', type: 0, children: [] }],
      listQuery: {
        pid: null,
        title: undefined
      },
      formData: {
        id: undefined,
        pid: 0,
        type: 0,
        title: '',
        name: '',
        component: '',
        sort: 9999,
        icon: '',
        path: '',
        frame: false,
        cache: false,
        hidden: false,
        permission: ''
      },
      hasDelObj: true,
      hasEdiObj: true,
      ids: [],
      title: '添加',
      dialogVisible: false,
      rules: {
        title: [{ required: true, message: '请输入菜单标题', trigger: 'blur' }],
        path: [{ required: true, message: '请输入路由地址', trigger: 'blur' }]
      }
    }
  },
  created() {
    this.queryAll()
  },
  methods: {
    // 打开添加修改对话框
    openDialog() {
      tree().then(res => {
        this.$nextTick(() => {
          this.menus[0].children = res
        })
      })
    },
    // 点击查询
    handleFilter() {
      this.queryAll()
    },
    // 查询
    queryAll() {
      this.loading = true
      this.tableData = []
      findAll(this.listQuery).then(res => {
        this.tableData = res
        this.columnNames = this.$refs.table.columns.map(c => {
          return c.label
            ? { label: c.label, visible: false }
            : { label: '', visible: false }
        })
        console.log(this.columnNames)
        this.tableRef = this.$refs.table
        const vm = this.$refs.table.$children.find(e => e.prop === '菜单标题')
        console.log(vm)

        setTimeout(() => {
          this.loading = false
        }, 500)
      }).catch(() => {
        this.loading = false
      })
    },
    sortChange(column, prop, order) {

    },
    // 懒加载
    load(tree, treeNode, resolve) {
      setTimeout(() => {
        findByPid(tree.id).then(res => {
          resolve(res)
        })
      }, 1000)
    },
    // 选中
    handleSelectionChange(val) {
      this.selectionChange = val
      this.ids.length = 0
      const _this = this
      if (val.length > 0) {
        this.hasEdiObj = val.length !== 1
        this.hasDelObj = false
      } else {
        this.hasDelObj = true
        this.hasEdiObj = true
      }
      val.forEach((element) => {
        _this.ids.push(element.id)
      })
    },
    // 重置
    resetForm() {
      this.listQuery = { title: undefined }
      this.handleFilter()
    },
    // 点击添加子菜单
    handleSubCreate(row) {
      this.formData = {
        id: undefined,
        pid: row.id,
        type: row.type === 0 ? 1 : row.type === 1 ? 2 : row.type === 2 ? 2 : 0,
        title: '',
        name: '',
        component: '',
        sort: 9999,
        icon: '',
        path: '',
        frame: false,
        cache: false,
        hidden: false,
        permission: ''
      }
      this.title = '添加'
      this.dialogVisible = true
      this.$nextTick(() => {
        this.$refs['formData'].clearValidate()
      })
    },
    // 点击添加按钮
    handleCreate() {
      this.formData = {
        id: undefined,
        pid: 0,
        type: 0,
        title: '',
        name: '',
        component: '',
        sort: 9999,
        icon: '',
        path: '',
        frame: false,
        cache: false,
        hidden: false,
        permission: ''
      }
      this.title = '添加'
      this.dialogVisible = true
      this.$nextTick(() => {
        this.$refs['formData'].clearValidate()
      })
    },
    // 点击更新按钮
    handleUpdate(row) {
      this.formData = Object.assign({}, row) // copy obj
      this.title = '修改'
      this.dialogVisible = true
      this.$nextTick(() => {
        this.$refs['formData'].clearValidate()
      })
    },
    // 点击删除按钮
    handleDelete() {
      if (this.ids.length === 0) {
        Notification.warning('请选择要删除的菜单')
        return
      }
      this.$confirm('此操作将永久删除该记录, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.deleteByIds(this.ids)
      })
    },
    // 创建
    create() {
      this.$refs['formData'].validate((valid) => {
        if (!valid) return
        create(this.formData).then(res => {
          this.dialogVisible = false
          Notification.success(res)
          this.handleFilter()
        })
      })
    },
    // 更新
    updateById() {
      this.$refs['formData'].validate((valid) => {
        if (!valid) return
        updateById(this.formData).then(res => {
          this.dialogVisible = false
          Notification.success(res)
          this.handleFilter()
        })
      })
    },
    // 更新外链
    updateFrame(data, tar) {
      updateById(data).then(res => {
        Notification.success(res)
      }).catch(err => {
        Notification.error(err)
        tar.frame = !tar.frame
      })
    },
    // 更新是否缓存
    updateCache(data, tar) {
      updateById(data).then(res => {
        Notification.success(res)
      }).catch(err => {
        Notification.error(err)
        tar.hidden = !tar.hidden
      })
    },
    // 更新是否隐藏
    updateHidden(data, tar) {
      updateById(data).then(res => {
        Notification.success(res)
      }).catch(err => {
        Notification.error(err)
        tar.hidden = !tar.hidden
      })
    },
    // 删除
    deleteByIds(ids) {
      if (ids.length > 0) {
        deleteByIds(ids).then(res => {
          Notification.success(res)
          this.handleFilter()
        })
      }
    },
    // 选中图标
    selected(name) {
      this.formData.icon = name
    }
  }
}
</script>

<style scoped>
.opts {
  padding: 4px 0;
  display: -webkit-flex;
  display: flex;
  align-items: center;
}

.opts {
  margin-left: auto;
}
</style>
